﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using ProjBackEnd.DBInstance;
using ProjBackEnd.Lib;
using System.Reflection;
using System.Diagnostics;
using ProjBackEnd.Areas.Sys.Models;
using System.Data;

namespace ProjBackEnd.DAL
{
    /// <summary>
    /// 用户逻辑
    /// </summary>
    public class userLogic
    {
        /// <summary>
        /// 注册用户
        /// </summary>
        /// <param name="_strMpno">手机号</param>
        /// <param name="_strPassword">密码</param>
        /// <param name="_strUsername">用户姓名</param>
        /// <param name="_strUserid"></param>
        /// <param name="_strDeptcd"></param>
        /// <returns>正常完成注册返回生成的memberid；所注册的用户名已在系统中存在时返回"0"；异常时返回 ""；</returns>
        public static string RegMember(string _strMpno, string _strPassword, string _strUsername="",string _strUserid="",string _strDeptcd="")
        {
            ProjUserInfoDataContext puctx = new ProjUserInfoDataContext(sysLogic.GetConnString(sysLogic.DataBaseName.PROJ));
            SYS_USERTB entity = new SYS_USERTB();
            string strMemberid = "";
            try
            {
                if (0 != puctx.SYS_USERTB.Where(n => n.mpno == _strMpno || n.userid == _strUserid).ToList().Count)
                {
                    strMemberid = "0";
                    return strMemberid;
                }

                int iMemberid = puctx.SP_GETMASTERKEY("MEMBERID");
                if (iMemberid != -1) strMemberid = iMemberid.ToString("0000000000");
                else throw new Exception("Get memberid Error.#-1");
                int iUserid = puctx.SP_GETMASTERKEY("USERID");
                if (iUserid == -1) throw new Exception("Get userid Error.#-1");

                entity.memberid = strMemberid;
                entity.avatar = "";
                entity.mpno = _strMpno;
                entity.nickname = _strUsername;
                entity.password = _strPassword;
                entity.regdt = DateTime.Now;
                entity.stat = "N";
                entity.username = _strUsername;
                entity.dept = _strDeptcd??"";
                //userid后期允许用户自行修改（注意修改时不能与任意手机号相同），但因涉及登录，所以不能重复，且要与memberid区分
                entity.userid = string.IsNullOrEmpty(_strUserid) ? "U" + ((new Random()).Next(100000000) + (iUserid * 100000000)).ToString() : _strUserid;
                puctx.SYS_USERTB.InsertOnSubmit(entity);
                puctx.SubmitChanges();
            }
            catch (Exception ex)
            {
                strMemberid = "";
                DataUtil.WriteLog(MethodBase.GetCurrentMethod().Name, ex.Message);
            }
            return strMemberid;
        }

        /// <summary>
        /// 用户校验
        /// </summary>
        /// <param name="_strLoginid">登录名。对于自动登录，登录名是内置id；对于手动登录，登录名是手机号或userid</param>
        /// <param name="_strPassword">登录密码</param>
        /// <param name="_isAutoLogin">是否自动登录</param>
        /// <returns>用户信息</returns>
        public static UserInfo_LoginSucc CheckMember(string _strLoginid, string _strPassword, bool _isAutoLogin)
        {
            UserInfo_LoginSucc collecReturn = new UserInfo_LoginSucc();
            ProjUserInfoDataContext puctx = new ProjUserInfoDataContext(sysLogic.GetConnString(sysLogic.DataBaseName.PROJ));
            SYS_USERTB entityUser = new SYS_USERTB();
            //try
            //{
            if (_isAutoLogin)
            {
                entityUser = puctx.SYS_USERTB.SingleOrDefault(n => (n.memberid == _strLoginid) && (n.stat != "F"));
            }
            else
            {
                entityUser = puctx.SYS_USERTB.SingleOrDefault(n => (n.mpno == _strLoginid) || (n.userid.ToUpper() == _strLoginid.ToUpper()) && (n.stat != "F"));
            }

            if (entityUser == default(SYS_USERTB))
                return default(UserInfo_LoginSucc);

            string strPassEncrypt = "";
            if (_isAutoLogin)
            {
                strPassEncrypt = _strPassword;
            }
            else
            {
                strPassEncrypt = DataUtil.EncryptPassword(_strPassword);
            }

            if (strPassEncrypt != entityUser.password)
                return default(UserInfo_LoginSucc);

            collecReturn.avatar = entityUser.avatar;
            collecReturn.memberid = entityUser.memberid;
            collecReturn.mpno = entityUser.mpno;
            collecReturn.optlb = "X";
            collecReturn.userid = entityUser.userid;
            collecReturn.username = entityUser.username;
            collecReturn.deptcd = entityUser.dept;
            //}
            //catch (Exception ex) { DataUtil.WriteLog(MethodBase.GetCurrentMethod().Name, ex.Message); }
            //finally { puctx.Connection.Close(); }
            return collecReturn;
        }

        /// <summary>
        /// 检查token是否合法
        /// </summary>
        /// <param name="_strMemberid">memberid</param>
        /// <param name="_token">Token</param>
        /// <param name="_strPlatcd">平台代码</param>
        /// <returns>true：合法；false：不合法</returns>
        public static bool CheckToken(string _strMemberid, string _token,string _strPlatcd)
        {
            ProjUserInfoDataContext puctx = new ProjUserInfoDataContext(sysLogic.GetConnString(sysLogic.DataBaseName.PROJ));
            try
            {
                if (string.IsNullOrEmpty(_strMemberid)) throw new Exception("用户名非法");
                if (default(SYS_USERTB) == puctx.SYS_USERTB.SingleOrDefault(n => n.memberid == _strMemberid && n.stat != "F")) //****待优化
                    throw new Exception("未找到非冻结用户" + _strMemberid);
                SYS_USERLOGIN entity = new SYS_USERLOGIN();
                entity = puctx.SYS_USERLOGIN.SingleOrDefault(n => n.memberid == _strMemberid
                                                                                                   && n.token == _token && n.tokenexpire >= DateTime.Now
                                                                                                   && n.platcd == _strPlatcd.ToUpper());
                if (entity == default(SYS_USERLOGIN)) return false;
                else
                {
                    DateTime dt = DateTime.Now;
                    DateTime dtExpire = entity.tokenexpire == null ? dt : entity.tokenexpire;
                    if ((dtExpire - dt).Hours > 12) return true; //token还有12小时到期时再更新过期时间，以避免频繁更新数据库
                    entity.logindt = dt;
                    entity.tokenexpire = dt.AddHours(168);
                    puctx.SubmitChanges();
                    return true;
                }
            }
            catch (Exception ex)
            {
                StackTrace trace = new StackTrace();
                StackFrame frame = trace.GetFrame(1); //1代表上级，2代表上上级，以此类推  
                MethodBase method = frame.GetMethod();
                string sParent = method.Name;
                string strMemberid = string.IsNullOrEmpty(_strMemberid) ? "用户名Null" : _strMemberid;
                DataUtil.WriteLog(MethodBase.GetCurrentMethod().Name, ex.Message + "**" + (ex.InnerException==null?"": ex.InnerException.Message) + "**" + strMemberid + "**" + _token + "**Parent:" + sParent);
                return false;
            }
            finally { if (puctx.Connection.State != System.Data.ConnectionState.Closed) puctx.Connection.Close(); }
        }

        /// <summary>
        /// 获取Token
        /// </summary>
        /// <param name="_strMemberid"></param>
        /// <param name="_strPlatcd"></param>
        /// <param name="_strToken"></param>
        /// <returns></returns>
        public static int GetToken(string _strMemberid, string _strPlatcd, out string _strToken)
        {
            ProjUserInfoDataContext puctx = new ProjUserInfoDataContext(sysLogic.GetConnString(sysLogic.DataBaseName.PROJ));

            _strToken = "";
            DateTime dtNow = DateTime.Now;
            //try
            //{
            int iUserCount = puctx.SYS_USERTB.Count(n => n.memberid == _strMemberid && n.stat != "F");
            if (iUserCount != 1) throw new Exception("未找到非冻结用户" + _strMemberid);
            List<SYS_USERLOGIN> lst = puctx.SYS_USERLOGIN.Where(n => n.memberid == _strMemberid && n.platcd == _strPlatcd.ToUpper()).ToList();
            if (lst.Count() == 0) //如果用户从未登录
            {
                SYS_USERLOGIN collecUl = new SYS_USERLOGIN();
                _strToken = Guid.NewGuid().ToString("N");
                collecUl.token = _strToken;
                collecUl.devicebrand = ""; //更新手机品牌以便确定推送引擎
                collecUl.deviceid = "";
                collecUl.memberid = _strMemberid;
                collecUl.platcd = _strPlatcd.ToUpper();
                collecUl.tokenexpire = dtNow.AddHours(168); //令牌过期时间
                collecUl.ostp = "";
                collecUl.logindt = dtNow;
                puctx.SYS_USERLOGIN.InsertOnSubmit(collecUl);
            }
            else
            {
                _strToken = lst[0].token;
                //用户仅登录过app未登录过pc时，PcTokenExpire值为null，此时将令牌过期时间调整为当前时间后24小时
                DateTime dtExpire = lst[0].tokenexpire;
                //PC端暂不设置单点登录功能，后续如果要加入此功能，则仅保留else段即可
                if (dtExpire > dtNow) //token未过期
                    _strToken = lst[0].token;
                else
                {
                    lst[0].logindt = dtNow;
                    lst[0].token = Guid.NewGuid().ToString("N"); //如果【用户的PC令牌已过期】，则生成新的PC令牌
                    lst[0].tokenexpire = dtNow.AddHours(168); //令牌过期时间 7 天
                }
            }

            puctx.SubmitChanges();
            return 0;
            //}
            //catch (Exception ex)
            //{
            //    DataUtil.WriteLog(MethodBase.GetCurrentMethod().Name, ex.Message);
            //    _strToken = "";
            //    return 90005;
            //}

        }

        /// <summary>
        /// 检测用户是否存在
        /// </summary>
        /// <param name="_strMpno">用户手机号</param>
        /// <param name="_strUserid">用户登录名</param>
        /// <returns>用户基础信息</returns>
        public static bool CheckUserExsit(string _strMpno, string _strUserid)
        {
            ProjUserInfoDataContext puctx = new ProjUserInfoDataContext(sysLogic.GetConnString(sysLogic.DataBaseName.PROJ));
            List<SYS_USERTB> lst = new List<SYS_USERTB>();
            try
            {
                IEnumerable<SYS_USERTB> ieUser = puctx.SYS_USERTB.Where(n => (n.mpno == _strMpno) || (n.userid.ToUpper() == _strUserid.ToUpper()) && (n.stat != "F"));
                if (ieUser.Count() == 0) return false;
                else return true;
            }
            catch (Exception ex) { DataUtil.WriteLog(MethodBase.GetCurrentMethod().Name, ex.Message); return false; }
            finally { if (puctx.Connection.State != ConnectionState.Closed) puctx.Connection.Close(); }
        }
        /// <summary>
        /// 检查用户是否存在
        /// </summary>
        /// <param name="_strMemberid"></param>
        /// <returns></returns>
        public static bool CheckUserExsit(string _strMemberid)
        {
            ProjUserInfoDataContext puctx = new ProjUserInfoDataContext(sysLogic.GetConnString(sysLogic.DataBaseName.PROJ));
            try
            {
                List<SYS_USERTB> lst = puctx.SYS_USERTB.Where(n => n.memberid == _strMemberid && (n.stat != "F")).ToList();
                if (lst.Count != 1) return false;
                return true;
            }
            catch (Exception ex) { DataUtil.WriteLog(MethodBase.GetCurrentMethod().Name, ex.Message); return false; }
            finally { if (puctx.Connection.State != System.Data.ConnectionState.Closed) puctx.Connection.Close(); }
        }
        /// <summary>
        /// 获取用户权限
        /// </summary>
        /// <param name="_strMemberid"></param>
        /// <param name="_strComcd"></param>
        /// <returns></returns>
        public static List<VIEW_SYS_USERPERMISSION> GetUserPermission(string _strMemberid, string _strComcd)
        {
            ProjUserInfoDataContext puctx = new ProjUserInfoDataContext(sysLogic.GetConnString(sysLogic.DataBaseName.PROJ));
            List<VIEW_SYS_USERPERMISSION> lst = new List<VIEW_SYS_USERPERMISSION>();
            try
            {
                lst = puctx.VIEW_SYS_USERPERMISSION.Where(n => n.memberid == _strMemberid && n.comcd == _strComcd.ToUpper()).OrderBy(n => n.menuorder).ToList();
            }
            catch (Exception ex) { DataUtil.WriteLog(MethodBase.GetCurrentMethod().Name, ex.Message); lst.Clear(); }
            finally { if (puctx.Connection.State != System.Data.ConnectionState.Closed) puctx.Connection.Close(); }
            return lst;
        }
        /// <summary>
        /// 获取单一公司用户
        /// </summary>
        /// <param name="_strComcd"></param>
        /// <param name="_strDeptcd"></param>
        /// <param name="_strMpno"></param>
        /// <param name="_strUserid"></param>
        /// <param name="_strMemberid"></param>
        /// <returns></returns>
        public static RespSysUserInfo GetComUsers(string _strComcd,string _strDeptcd,string _strMpno,string _strUserid,string _strMemberid)
        {
            RespSysUserInfo respReturn = new RespSysUserInfo();
            List<ComUserInfo> lst = new List<ComUserInfo>();
            ProjUserInfoDataContext puctx = new ProjUserInfoDataContext(sysLogic.GetConnString(sysLogic.DataBaseName.PROJ));
            try
            {
                IEnumerable<VIEW_CD_COMDEPTUSER> ieUser = puctx.VIEW_CD_COMDEPTUSER.Where(n => (string.IsNullOrEmpty(_strComcd) ? true : n.comcd == _strComcd)
                                                                                                                                                             && (string.IsNullOrEmpty(_strDeptcd) ? true : n.deptcd == _strDeptcd)
                                                                                                                                                             && (string.IsNullOrEmpty(_strMpno) ? true : n.mpno == _strMpno)
                                                                                                                                                             && (string.IsNullOrEmpty(_strUserid) ? true : n.userid == _strUserid)
                                                                                                                                                             && (string.IsNullOrEmpty(_strMemberid) ? true : n.memberid == _strMemberid)
                                                                                                                                                             );
                foreach (VIEW_CD_COMDEPTUSER _entity in ieUser)
                {
                    ComUserInfo collec = new ComUserInfo();
                    collec.comcd = _strComcd;
                    collec.comnm =  _entity.comnm;
                    collec.deptcd = _entity.deptcd;
                    collec.deptnm =  _entity.deptnm;
                    collec.memberid = _entity.memberid;
                    collec.mpno = _entity.mpno;
                    collec.optlb = "X";
                    collec.stat = _entity.stat;
                    collec.userid = _entity.userid;
                    collec.username = _entity.username;
                    lst.Add(collec);
                }
                ResultUsers res = new ResultUsers();
                res.userlist = lst;
                respReturn.result = res;
                respReturn.statusCode = 0;
                respReturn.statusMsg = "";
            }
            catch (Exception ex) { lst.Clear(); DataUtil.WriteLog(MethodBase.GetCurrentMethod().Name, ex.Message); }
            finally { if (puctx.Connection.State != ConnectionState.Closed) puctx.Connection.Close(); }
            return respReturn;
        }
        /// <summary>
        /// 更新用户信息
        /// </summary>
        /// <param name="_collec"></param>
        /// <returns></returns>
        public static RespSysNullResultInfo UpdateUserInfo(UserInfo_Modify _collec)
        {
            RespSysNullResultInfo respReturn = new RespSysNullResultInfo();
            ProjUserInfoDataContext puctx = new ProjUserInfoDataContext(sysLogic.GetConnString(sysLogic.DataBaseName.PROJ));
            try
            {
                SYS_USERTB entityUser = puctx.SYS_USERTB.SingleOrDefault(n => n.memberid == _collec.memberid);
                if(entityUser==default(SYS_USERTB))
                {
                    respReturn.statusCode = 10018;
                    respReturn.statusMsg = "用户不存在";
                    return respReturn;
                }

                if (!string.IsNullOrEmpty(_collec.userid) && entityUser.userid != _collec.userid)
                {
                    if( puctx.SYS_USERTB.Count(n => n.userid == _collec.userid || n.memberid == _collec.memberid) >0)
                    {
                        respReturn.statusCode = 10034;
                        respReturn.statusMsg = "用户id已存在";
                        return respReturn;
                    }
                }
                entityUser.userid = string.IsNullOrEmpty(_collec.userid) ? entityUser.userid : _collec.userid;
                entityUser.avatar = string.IsNullOrEmpty(_collec.avatar) ? entityUser.avatar : _collec.avatar;
                entityUser.mpno = string.IsNullOrEmpty(_collec.mpno) ? entityUser.mpno : _collec.mpno;
                entityUser.nickname = string.IsNullOrEmpty(_collec.nickname) ? entityUser.nickname : _collec.nickname;
                entityUser.dept = string.IsNullOrEmpty(_collec.deptcd) ? entityUser.dept : _collec.deptcd;

                entityUser.password = string.IsNullOrEmpty(_collec.password) ? entityUser.password : DataUtil.EncryptPassword(_collec.password);

                entityUser.username = string.IsNullOrEmpty(_collec.username) ? entityUser.username : _collec.username;
                puctx.SubmitChanges();
                respReturn.statusCode = 0;
                respReturn.statusMsg = "更新成功";
            }
            catch (Exception ex)
            {
                DataUtil.WriteLog(MethodBase.GetCurrentMethod().Name, ex.Message);
                respReturn.statusCode = 0;
                respReturn.statusMsg = "数据访问异常。" + ex.Message;
            }
            finally { if (puctx.Connection.State != ConnectionState.Closed) puctx.Connection.Close(); }
            return respReturn;
        }
        /// <summary>
        /// 自助修改密码
        /// </summary>
        /// <param name="_strMemberid"></param>
        /// <param name="_strOrigPwd"></param>
        /// <param name="_strNewPwd"></param>
        /// <returns></returns>
        public static RespSysNullResultInfo ChangeSelfPassword(string _strMemberid,string _strOrigPwd,string _strNewPwd)
        {
            RespSysNullResultInfo respReturn = new RespSysNullResultInfo();
            ProjUserInfoDataContext puctx = new ProjUserInfoDataContext(sysLogic.GetConnString(sysLogic.DataBaseName.PROJ));
            try
            {
                SYS_USERTB entity = puctx.SYS_USERTB.SingleOrDefault(n => n.memberid == _strMemberid);
                if (entity == default(SYS_USERTB)) throw new BizException("未找到用户信息");
                if (entity.stat == "N") throw new BizException("冻结用户不能自助修改密码");
                string strOrigPwdEncrypt = DataUtil.EncryptPassword(_strOrigPwd);
                if(entity.password!=strOrigPwdEncrypt) throw new BizException("原始密码错误");
                entity.password = DataUtil.EncryptPassword(_strNewPwd);
                puctx.SubmitChanges();
            }
            catch (BizException ex)
            {
                DataUtil.WriteLog(MethodBase.GetCurrentMethod().Name, ex.Message);
                respReturn.statusCode = 90021;
                respReturn.statusMsg = ex.Message;
            }
            catch (Exception ex)
            {
                DataUtil.WriteLog(MethodBase.GetCurrentMethod().Name, ex.Message);
                respReturn.statusCode = 90005;
                respReturn.statusMsg = "数据访问异常。" + ex.Message;
            }
            finally { if (puctx.Connection.State != ConnectionState.Closed) puctx.Connection.Close(); }
            return respReturn;
        }

        /// <summary>
        /// 审批敏感操作检验
        /// </summary>
        /// <param name="_strMemberid"></param>
        /// <param name="_strComcd"></param>
        /// <returns></returns>
        public static bool CheckApproveSensPermission_I(string _strMemberid,string _strComcd)
        {
            BizPurviewDataContext bpctx = new BizPurviewDataContext(sysLogic.GetConnString(sysLogic.DataBaseName.PROJ));
            try
            {
                int iPurCount = bpctx.PUR_MANAGERTB.Count(n => n.memberid == _strMemberid && n.purtp == GlobalSettings.PURTP_APVSENS && n.comcd == _strComcd);
                if (iPurCount == 0) throw new BizException("无操作权限。#" + _strMemberid + "@" + _strComcd);
                return true;
            }
            catch (BizException ex)
            {
                DataUtil.WriteLog(MethodBase.GetCurrentMethod().Name, ex.Message);
                return false;
            }
            catch (Exception ex)
            {
                DataUtil.WriteLog(MethodBase.GetCurrentMethod().Name, ex.Message);
                return false;
            }
            finally
            {
                if (bpctx.Connection.State != ConnectionState.Closed) bpctx.Connection.Close();
            }
        }

    }
}